﻿using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TestSpyApi
{
    public partial class Form3 : Form
    {
        public Form3()
        {
            InitializeComponent();
        }

        //Define TreeView Flags and Messages
        private const int BN_CLICKED = 0xF5;
        private const int TV_FIRST = 0x1100;
        private const int TVGN_ROOT = 0x0;
        private const int TVGN_NEXT = 0x1;
        private const int TVGN_CHILD = 0x4;
        private const int TVGN_FIRSTVISIBLE = 0x5;
        private const int TVGN_NEXTVISIBLE = 0x6;
        private const int TVGN_CARET = 0x9;
        private const int TVM_SELECTITEM = (TV_FIRST + 11);
        private const int TVM_GETNEXTITEM = (TV_FIRST + 10);
        private const int TVM_GETITEM = (TV_FIRST + 12);
        private const int TVM_GETCOUNT = (TV_FIRST + 5);
        private const int TVM_EXPAND = (TV_FIRST + 2);

        public const int TVE_COLLAPSE = 0x0001;
        public const int TVE_EXPAND = 0x0002;

        private const int WM_LBUTTONDBLCLK = 0x0203;
        private const int MK_LBUTTON = 0x0001;

        private const int LVM_FIRST = 0x1000;
        private const int LVM_GETITEMCOUNT = 0x1004;//获取列表行数
        private const int LVM_GETITEMTEXT = 0x102D;
        private const int LVM_GETNEXTITEM = (LVM_FIRST + 12);
        private const int HDM_GETITEMCOUNT = 0x1200;//获取列表列数

        //Find Window API
        [DllImport("User32.dll")]
        public static extern Int32 FindWindow(String lpClassName, String lpWindowName);

        //Find WindowEx API
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);

        //Send Message API
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SendMessage(int hWnd, int msg, int wParam, IntPtr lParam);

        static IntPtr Make_WM_LBUTTONDBLCLK_LParam(int LoWord, int HiWord)
        {
            return (IntPtr)((HiWord << 16) | (LoWord & 0xffff));
        }

        private void Start()
        {
            //Handle variables
            int hwnd = 0;
            int treeItem = 0;
            IntPtr hwndChild = IntPtr.Zero;
            IntPtr treeChild = IntPtr.Zero;
            IntPtr listChild = IntPtr.Zero;

            hwnd = FindWindow(null, "张恒恒-中联医院信息系统(旗舰版)-(锁屏：Ctrl+Alt+L)"); //Handle for the application to be controlled
            label1.Text = string.Format("1、匹配HIS主界面：{0}", hwnd > 0 ? "passed" : "failed");
            if (hwnd > 0)
            {
                // 左侧菜单操作
                treeChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "TreeView20WndClass", null);
                int count = SendMessage((int)treeChild, TVM_GETCOUNT, 0, (IntPtr)0);
                label2.Text = string.Format("2、匹配[{0}]HIS主界面左侧TreeView菜单, 共计包含菜单项: {1}个", treeChild != IntPtr.Zero ? "passed" : "failed", count);

                treeItem = SendMessage((int)treeChild, TVM_GETNEXTITEM, TVGN_ROOT, IntPtr.Zero);//获取（第一个）Root节点Handle
                int isSelected = SendMessage((int)treeChild, TVM_SELECTITEM, TVGN_CARET, (IntPtr)treeItem);//焦点选择（第一个）Root节点使其显示在可见区域
                int isExpanded = SendMessage((int)treeChild, TVM_EXPAND, TVM_EXPAND, (IntPtr)treeItem);//展开（第一个）Root节点
                label3.Text = string.Format("3、焦点选择[{0}]并展开[{1}]左侧TreeView菜单第一项", isSelected > 0 ? "passed" : "failed", isExpanded > 0 ? "passed" : "failed");

                treeItem = SendMessage((int)treeChild, TVM_GETNEXTITEM, TVGN_NEXT, (IntPtr)treeItem);//获取（第二个）Root节点Handle
                treeItem = SendMessage((int)treeChild, TVM_GETNEXTITEM, TVGN_NEXT, (IntPtr)treeItem);//获取（第三个）Root节点Handle

                string nodeText = TreeViewWinAPI.GetTreeItemText(treeChild, (IntPtr)treeItem);
                label4.Text = string.Format("4、获取左侧TreeView菜单第三项的文本： {0}", nodeText);
                //isSelected = SendMessage((int)treeChild, TVM_SELECTITEM, TVGN_CARET, (IntPtr)treeItem);//展示（第三个）Root节点使其显示在可见区域
                var rect = TreeViewWinAPI.GetTreeItemRect(treeChild, (IntPtr)treeItem);
                label5.Text = string.Format("5、获取左侧TreeView菜单第三项的位置： top:{0}, left:{1}, right:{2}, botton:{3}", rect.top, rect.left, rect.right, rect.bottom);
                //isExpanded = SendMessage((int)treeChild, TVM_EXPAND, TVE_EXPAND, (IntPtr)treeItem);//展开（第三个）Root节点
                isExpanded = SendMessage((int)treeChild, WM_LBUTTONDBLCLK, MK_LBUTTON, Make_WM_LBUTTONDBLCLK_LParam(rect.left, rect.top));//模拟鼠标左键点击（第三个）Root节点
                label6.Text = string.Format("6、鼠标点击[{0}]左侧TreeView菜单第三项", isExpanded == 0 ? "passed" : "failed");

                

                // 主区域ListView操作ListView20WndClass
                listChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "ListView20WndClass", null);
                int listCount = SendMessage((int)listChild, LVM_GETITEMCOUNT, 0, (IntPtr)0);
                string listItemText = ListViewWinAPI.GetListItemText(listChild, 9, 0);
                label7.Text = string.Format("7、获取主区域ListView的当前内容数量： {0}, 第十项的内容为：{1}", listCount, listItemText);

                var rect2 = ListViewWinAPI.GetListItemRect(treeChild, 9);
                label8.Text = string.Format("8、获取主区域ListView的第十项的位置： top:{0}, left:{1}, right:{2}, botton:{3}", rect2.top, rect2.left, rect2.right, rect2.bottom);
                var isClicked = -1;// SendMessage((int)treeChild, WM_LBUTTONDBLCLK, MK_LBUTTON, Make_WM_LBUTTONDBLCLK_LParam(rect2.left, rect2.top));//模拟鼠标左键点击（第十个）节点
                var isOpened = -1;
                label9.Text = string.Format("9、鼠标点击[{0}]主区域ListView菜单第十项，打开新程序窗口[{1}]", isClicked == 0 ? "passed" : "failed", isOpened == 0 ? "passed" : "failed");


                //SendMessage((int)listChild, LVM_GETNEXTITEM, -1, LVNI_FOCUSED | LVNI_SELECTED);

                label10.Text = "10、操作正常结束";
            }
        }//END Scan

        private void ResetLabels()
        {
            label1.Text = "";
            label2.Text = "";
            label3.Text = "";
            label4.Text = "";
            label5.Text = "";
            label6.Text = "";
            label7.Text = "";
            label8.Text = "";
            label9.Text = "";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ResetLabels();
            Start();
        }
    }
}
